#include "stdafx.h"
#include "CSensorEvents.h"
#include "CSensorManagerEvents.h"
#include <Sensorsapi.h>
#include <sensors.h>
#include <SensAPI.h>
#include <initguid.h>
#include <propkeydef.h>
#include <comutil.h>
#include <math.h>

#define DEBUG 1

CSensorEvents::CSensorEvents(CSensorManagerEvents* sensorManagerEvents)
{//	puts(__FUNCTION__);
	m_lRefCount = 1; //ref count initialized to 1
	m_pSensorManagerEvents = sensorManagerEvents;
	icnt = 0;
}

CSensorEvents::~CSensorEvents(void)
{//	puts(__FUNCTION__);
//	m_mapLux.RemoveAll();
}

STDMETHODIMP CSensorEvents::QueryInterface(REFIID riid, void** ppObject)
{//	puts(__FUNCTION__);
	HRESULT hr = S_OK;

	*ppObject = NULL;
	if (riid == __uuidof(ISensorEvents))
	{
		*ppObject = reinterpret_cast<ISensorEvents*>(this);
	}
	else if (riid == IID_IUnknown)
	{
		*ppObject = reinterpret_cast<IUnknown*>(this);
	}
	else
	{
		hr = E_NOINTERFACE;
	}

	if (SUCCEEDED(hr))
	{
		(reinterpret_cast<IUnknown*>(*ppObject))->AddRef();
	}

	return hr;
}

ULONG _stdcall CSensorEvents::AddRef()
{//	puts(__FUNCTION__);
	m_lRefCount++;
	return m_lRefCount; 
}

ULONG _stdcall CSensorEvents::Release()
{//	puts(__FUNCTION__);
	ULONG lRet = --m_lRefCount;

	if (m_lRefCount == 0)
	{
		delete this;
	}

	return lRet;
}

HRESULT CSensorEvents::OnStateChanged(ISensor *pSensor, SensorState state)
{//	puts(__FUNCTION__);
	HRESULT hr = S_OK;

	if (NULL != pSensor)
	{
		SENSOR_ID idSensor = GUID_NULL;
		hr = pSensor->GetID(&idSensor);
		if (SUCCEEDED(hr))
		{
			if (SENSOR_STATE_READY == state)
			{
				hr = GetSensorData(pSensor);
				hr = UpdateXYZ();
			}
			else
			{
				hr = UpdateXYZ();
			}
		}
	}
	else
	{
		hr = E_POINTER;
	}

	return hr;
}

HRESULT CSensorEvents::OnDataUpdated(ISensor *pSensor, ISensorDataReport *pNewData)
{	//puts(__FUNCTION__); 
	HRESULT hr = S_OK;

	if ((NULL != pSensor) && (NULL != pNewData))
	{
		PROPVARIANT varM = {};

		hr = pNewData->GetSensorValue(SENSOR_DATA_TYPE_MAGNETIC_HEADING_COMPENSATED_MAGNETIC_NORTH_DEGREES, &varM);
		if(hr == S_OK)
		{
			mapXYZ[0]=varM.dblVal;
			UpdateXYZ();
		}
	}
	else
	{
		hr = E_UNEXPECTED;
	}
	return hr;
}

HRESULT CSensorEvents::OnEvent(ISensor* /*pSensor*/, REFGUID /*eventID*/, IPortableDeviceValues* /*pEventData*/)
{
	// Not implemented
	return E_NOTIMPL;
}

HRESULT CSensorEvents::OnLeave(REFSENSOR_ID sensorID)
{//	puts(__FUNCTION__);
	return E_NOTIMPL;
}

HRESULT CSensorEvents::UpdateXYZ()
{//	puts(__FUNCTION__);
	HRESULT hr = S_OK;
	icnt++;
	printf("\rTURE NOTRH=%8.2f", mapXYZ[0]);
	DrawGraphics(mapXYZ[0]);
	/* rotate machine more than 90, pass */
	//if(icnt>20)
	//	if(mapXYZ[0]<=10 || mapXYZ[0]>=350){
	//		exit(0);
	//	}
	return hr;
}

HRESULT CSensorEvents::GetSensorData(ISensor* pSensor)
{//	puts("GetSensorData - No value");
	HRESULT hr = S_OK;

	if (NULL != pSensor)
	{
		CComPtr<ISensorDataReport> spDataReport;
		hr = pSensor->GetData(&spDataReport);
		if (SUCCEEDED(hr))
		{
			hr = GetSensorData(pSensor, spDataReport);
		}
		else
		{
			SENSOR_ID idSensor = GUID_NULL;
			hr = pSensor->GetID(&idSensor);
			if (SUCCEEDED(hr))
			{
				mapXYZ[0] = -1.0;
				mapXYZ[1] = -1.0;
				mapXYZ[2] = -1.0;
				hr = UpdateXYZ();
			}
		}
	}
	else
	{
#if DEBUG
		puts("-------------------------Error!");
#endif
		hr = E_POINTER;
	}

	return hr;
}

HRESULT CSensorEvents::GetSensorData(ISensor *pSensor, ISensorDataReport *pDataReport)
{//	puts("GetSensorData - No value");
	HRESULT hr = S_OK;

	if (NULL != pSensor && NULL != pDataReport)
	{
		SENSOR_ID idSensor = GUID_NULL;
		hr = pSensor->GetID(&idSensor);
		if (SUCCEEDED(hr))
		{
			PROPVARIANT pvV;
			PropVariantInit(&pvV);
			hr = pDataReport->GetSensorValue(SENSOR_DATA_TYPE_MAGNETIC_HEADING_TRUE_NORTH_DEGREES, &pvV);
			if (SUCCEEDED(hr))
			{
				mapXYZ[0] = V_R8(&pvV);
				hr = UpdateXYZ();
			}
			hr = pDataReport->GetSensorValue(SENSOR_DATA_TYPE_MAGNETIC_HEADING_X_DEGREES, &pvV);
			if (SUCCEEDED(hr))
			{
				mapXYZ[1] = V_R8(&pvV);
				hr = UpdateXYZ();
			}
			hr = pDataReport->GetSensorValue(SENSOR_DATA_TYPE_MAGNETIC_HEADING_X_DEGREES, &pvV);
			if (SUCCEEDED(hr))
			{
				mapXYZ[2] = V_R8(&pvV);
				hr = UpdateXYZ();
			}
//			UpdateXYZ();

			PropVariantClear(&pvV);
		}
	}
	else
	{
		puts("Error----------------------------------");
		hr = E_INVALIDARG;
	}

	return hr;
}